package it.kion.util.ui.ulog2.views;

import it.kion.util.ui.ulog2.Log4jPlugin;
import it.kion.util.ui.ulog2.Log4jUtil;
import it.kion.util.ui.ulog2.LoggingModel;
import it.kion.util.ui.ulog2.ReceiverThread;
import it.kion.util.ui.ulog2.Log4jPlugin.LEVELS;
import it.kion.util.ui.ulog2.views.actions.ShowDetailAction;

import java.util.ArrayList;

import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.AssertionFailedException;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.StatusLineContributionItem;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;

public class Log4jView extends TableViewPart {
	
	protected static final Image DEBUG_IMG = Log4jPlugin.getImageDescriptor(
			Log4jPlugin.getIconPath(LEVELS.DEBUG, false)).createImage();

	protected static final Image INFO_IMG = Log4jPlugin.getImageDescriptor(
			Log4jPlugin.getIconPath(LEVELS.INFO, false)).createImage();

	protected static final Image WARN_IMG = Log4jPlugin.getImageDescriptor(
			Log4jPlugin.getIconPath(LEVELS.WARN, false)).createImage();

	protected static final Image ERROR_IMG = Log4jPlugin.getImageDescriptor(
			Log4jPlugin.getIconPath(LEVELS.ERROR, false)).createImage();

	protected static final Image FATAL_IMG = Log4jPlugin.getImageDescriptor(
			Log4jPlugin.getIconPath(LEVELS.FATAL, false)).createImage();

	protected static final Image CONNECT_ICO = PlatformUI.getWorkbench()
			.getSharedImages().getImage(ISharedImages.IMG_ELCL_SYNCED);

	public static final int COL_IMAGE = 0;
	public static final int COL_TIME = 1;
	public static final int COL_LEVEL = 2;
	public static final int COL_MESSAGE = 3;
	public static final int COL_CATEGORY = 4;
	public static final int COL_METHOD = 5;

	public static final String ID = "it.kion.util.ui.ulog2.views.Log4jView";

	public ArrayList<String> getColumnHeaders() {
		ArrayList<String> list = new ArrayList<String>(columnHeaders.length);
		for (String s : columnHeaders) {
			list.add(s);
		}
		return list;
	}

	private static ColumnLayoutData columnLayoutsDefault[] = {
			new ColumnPixelData(19, false), new ColumnWeightData(75),
			new ColumnWeightData(50), new ColumnWeightData(200),
			new ColumnWeightData(100), new ColumnWeightData(75), };

	private TableViewer viewer;

	private StatusLineContributionItem statusLineContributionItem;

	public StatusLineContributionItem getStatusLineContributionItem() {
		return statusLineContributionItem;
	}

	private LoggingModel model;
	private LoggingListener modelListener;

	private Action deleteAction;
	private Action gotoAction;
	private Action pauseResumeServerAction;
	private ShowDetailAction showDetailAction;
	private IAction debugFilterAction, infoFilterAction, warnFilterAction,
			errorFilterAction, fatalFilterAction;

	public Log4jView() {
		super();
		initColDefault();
		model = Log4jPlugin.getDefault().getLoggingModel();
		modelListener = new LoggingListener();
		setColumnHeaders(columnHeaders);
		setColumnLayouts(columnLayouts);
	}

	private void initColDefault() {
		columnHeadersDefault = new String[6];
		columnHeadersDefault[0] = "";
		columnHeadersDefault[1] = Log4jUtil.DATA_CAPTION;
		columnHeadersDefault[2] = Log4jUtil.LIVELLO_CAPTION;
		columnHeadersDefault[3] = Log4jUtil.MESSAGGIO_CAPTION;
		columnHeadersDefault[4] = Log4jUtil.LOGGER_CAPTION;
		columnHeadersDefault[5] = Log4jUtil.LINEA_CAPTION;
		
		columnLayouts = columnLayoutsDefault;
	}

	public void createPartControl(Composite parent) {
		super.createPartControl(parent);
		viewer = getViewer();
		viewer.setContentProvider(model);
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setInput(ResourcesPlugin.getWorkspace());

		setDoubleClickAction(showDetailAction);

		setupActionToolbar(parent);

		Log4jUtil.initColorDefaults();

		model.addListener(modelListener);
		
	}

	private void setupActionToolbar(Composite parent) {
		IStatusLineManager statusLineManager = getViewSite().getActionBars()
				.getStatusLineManager();
		statusLineContributionItem = new StatusLineContributionItem(
				"it.kion.util.ui.ulog2.status");
		statusLineContributionItem.setVisible(true);
		statusLineContributionItem.setText("U-Log2");
		statusLineManager.insertBefore(StatusLineManager.END_GROUP,
				statusLineContributionItem);
		statusLineManager.update(true);
	}

	private class ULog2ActionToolbar extends Action {

		private final ImageDescriptor img, img_disab;
		private final String liv;
		private static final String ENABLE_MSG_BASE = "Click per abilitare il logging sul livello ";
		private static final String DISABLE_MSG_BASE = "Click per disabilitare il logging sul livello ";

		public ULog2ActionToolbar(LEVELS level) {
			super();
			img = Log4jPlugin.getImageDescriptor(Log4jPlugin.getIconPath(level,
					false));
			img_disab = Log4jPlugin.getImageDescriptor(Log4jPlugin.getIconPath(
					level, true));
			this.liv = level.toString();
			setImageDescriptor(img);
			setToolTipText("Click per disabilitare il logging sul livello "
					+ liv);
		}

		@Override
		public void run() {
			super.run();
			boolean enabled = Log4jPlugin.getDefault().isLevelEnabled(liv);
			if (enabled) {
				setImageDescriptor(img_disab);
				setToolTipText(DISABLE_MSG_BASE + liv);
				Log4jPlugin.getDefault().disableLevelFor(liv);
			} else {
				setImageDescriptor(img);
				setToolTipText(ENABLE_MSG_BASE + liv);
				Log4jPlugin.getDefault().enableLevelFor(liv);
			}
			// ULogUtilities.filterUpdated();
		}

	}

	private class PauseResumeServerAction extends Action {

		private final ImageDescriptor connect_img, img, img_disab;
		private static final String CONNECT_TOOLTIP = "Click per provare a riconnettere la socket del thread collettore dei log";
		private static final String ENABLE_TOOLTIP = "Click per sospendere il collezionamento dei log";
		private static final String DISABLE_TOOLTIP = "Click per riprendere il collezionamento dei log";
		private static final String CONNECT_TEXT = "Connetti!";
		private static final String ENABLE_TEXT = "Sospendi";
		private static final String DISABLE_TEXT = "Log!";

		public PauseResumeServerAction() {
			super();
			img = Log4jPlugin.getImageDescriptor(Log4jPlugin.PAUSE_ICO);
			img_disab = Log4jPlugin.getImageDescriptor(Log4jPlugin.RESUME_ICO);
			connect_img = Log4jPlugin.getImageDescriptor(Log4jPlugin.FATAL_ICO);
//			if (ReceiverThread.getRt().isConnected()) {
//			setImageDescriptor(img);
//			setText(ENABLE_TEXT);
//			setToolTipText(ENABLE_TOOLTIP);
//			} else {
//				setImageDescriptor(connect_img);
//				setText(CONNECT_TEXT);
//				setToolTipText(CONNECT_TOOLTIP);
//			}
			setImageDescriptor(connect_img);
			setText(CONNECT_TEXT);
			setToolTipText(CONNECT_TOOLTIP);
		}

		@Override
		public ImageDescriptor getImageDescriptor() {
//			ImageDescriptor res = ReceiverThread.getRt().isPaused() ? img
//					: img_disab;
//			boolean connected = ReceiverThread.getRt().isConnected();
//			if (!connected) {
//				res = connect_img;
//			}
//			return res;
			ImageDescriptor res = img;
			boolean connected = Log4jPlugin.getDefault().isConnected();
			if (!connected) {
				res = connect_img;
			}
			return res;
		}

		public void run() {
//			boolean connected = ReceiverThread.getRt().isConnected();
			boolean connected = Log4jPlugin.getDefault().isConnected();
			if (connected) {
//				boolean paused = ReceiverThread.getRt().isPaused();
//				ReceiverThread.getRt().setPaused(!paused);
//				setText(paused ? ENABLE_TEXT : DISABLE_TEXT);
//				setToolTipText(paused ? ENABLE_TOOLTIP : DISABLE_TOOLTIP);
//				setImageDescriptor(paused ? img : img_disab);
			} else {
//				setText(CONNECT_TEXT);
//				setToolTipText(CONNECT_TOOLTIP);
//				setImageDescriptor(connect_img);
//				ReceiverThread.changePort(ReceiverThread.getRt().getPort());
				Log4jPlugin.getDefault().setupReceiver();
			}
		}

	}

	public boolean isShowing() {
		boolean res = false;
		Table table = getTable();
		res = (table != null) && !(table.isDisposed());
		return res;
	}
//
//	public Table getTable() {
//		Table res = null;
//		if (viewer != null) {
//			res = viewer.getTable();
//		} else {
//			res = super.getTable();
//		}
//		return res;
//	}

	@Override
	public void init(IViewSite site) throws PartInitException {
		super.init(site);
		Log4jPlugin.setMSite(site);
	}

	protected void fillLocalPullDown(IMenuManager manager) {
		super.fillLocalPullDown(manager);
		manager.add(gotoAction);
		manager.add(new Separator());
		manager.add(deleteAction);
		manager.add(new Separator());
		// Bottoni di controllo del thread collettore
		manager.add(pauseResumeServerAction);
	}

	protected void fillContextMenu(IMenuManager manager) {
		super.fillContextMenu(manager);
		manager.add(gotoAction);
		manager.add(deleteAction);
		manager.add(new Separator("Additions"));
		// Bottoni di controllo del thread collettore
		manager.add(pauseResumeServerAction);

	}

	protected void fillLocalToolBar(IToolBarManager manager) {
		super.fillLocalToolBar(manager);

		manager.add(gotoAction);
		manager.add(deleteAction);
		manager.add(new Separator());

		// Bottoni di filtro per livello
		manager.add(debugFilterAction);
		manager.add(infoFilterAction);
		manager.add(warnFilterAction);
		manager.add(errorFilterAction);
		manager.add(fatalFilterAction);
		manager.add(new Separator());

		// Bottoni di controllo del thread collettore
		manager.add(pauseResumeServerAction);
	}

	protected void createActions() {
		super.createActions();
		deleteAction = new Action() {
			public void run() {
				getTable().setRedraw(false);
				model.clear();
				if (getViewer() != null
						&& !getViewer().getControl().isDisposed()) {
					try {
						getViewer().refresh(false);
					} catch (AssertionFailedException ae) {

					}
				}
				getTable().setRedraw(true);
			}
		};
		deleteAction.setText("Cancella");
		deleteAction.setToolTipText("Ripulisce la lista dei log");
		deleteAction.setImageDescriptor(PlatformUI.getWorkbench()
				.getSharedImages().getImageDescriptor(
						ISharedImages.IMG_TOOL_DELETE));

		gotoAction = new Action() {
			public void run() {
				ISelection selection = getViewer().getSelection();
				Object obj = ((IStructuredSelection) selection)
						.getFirstElement();
				if (obj != null) {
					LoggingEvent event = (LoggingEvent) obj;
					LocationInfo location = event.getLocationInformation();
					if (location != null) {
						Log4jUtil.linkToSource(location);
					}
				}
			}
		};
		gotoAction.setText("Vai a");
		gotoAction.setToolTipText("Vai a");
		gotoAction.setImageDescriptor(PlatformUI.getWorkbench()
				.getSharedImages().getImageDescriptor(
						ISharedImages.IMG_OBJ_FILE));

		// Action relative ai bottoni di toolbar
		debugFilterAction = new ULog2ActionToolbar(LEVELS.DEBUG);
		infoFilterAction = new ULog2ActionToolbar(LEVELS.INFO);
		warnFilterAction = new ULog2ActionToolbar(LEVELS.WARN);
		errorFilterAction = new ULog2ActionToolbar(LEVELS.ERROR);
		fatalFilterAction = new ULog2ActionToolbar(LEVELS.FATAL);

		// Action per la gestione del thread collettore.
		pauseResumeServerAction = new PauseResumeServerAction();
		
		// Apertura dettaglio
		showDetailAction = new ShowDetailAction(getTable());		
	}
	
	

	public void dispose() {
		model.removeListener(modelListener);
		super.dispose();
	}
}